﻿using System;
using System.Collections.Generic;
using System.Data.Objects;
using System.Linq;
using BusinessBingo.Common.Interfaces;
using BusinessBingo.Data.DataLoadOptions;
using BusinessBingo.Data.DataOrderOptions;
using BusinessBingo.Data.Filter;
using BusinessBingo.Data.Interfaces;
using BusinessBingo.Model;

namespace BusinessBingo.Data
{
    public class EFGroupRepository : EFBaseRepository, IGroupRepository
    {
        public EFGroupRepository(IUnitOfWork unitOfWork, IGuid portalGuid)
            : base(unitOfWork, portalGuid)
        {
        }

        public IList<Model.Group> GetItems(GroupDataLoadOptions dlo, GroupDataOrderOptions doo, GroupFilter filter)
        {
            ObjectQuery<Group> query = this.GetQuery(dlo, doo, filter);
            IList<Group> items = query.ToList();

            IList<Model.Group> result = new List<Model.Group>();

            foreach (Group item in items)
            {
                result.Add(Mapping.MapGroup(item));
            }

            return result;
        }
        
        public int GetItemsCount(GroupFilter filter)
        {
            ObjectQuery<Group> query = this.GetQuery(null, null, filter);
            return query.Count();
        }

        public Model.Group AddItem(Model.Group item)
        {
            item.Id = this._portalGuid.New;

            Data.Group g = Mapping.MapGroup(item);
            g.Id = item.Id;

            _context.Groups.AddObject(g);

            return item;
        }

        public ObjectQuery<Data.Group> GetQuery(GroupDataLoadOptions dlo, GroupDataOrderOptions doo, GroupFilter filter)
        {
            ObjectQuery<Group> query = this._context.Groups;

            return query.LoadWith(dlo).FilterFor(filter).OrderBy(doo);
        }
    }

    internal static class GroupQueryExtensions
    {
        public static ObjectQuery<Group> FilterFor(this ObjectQuery<Group> query, GroupFilter filter)
        {
            if (filter == null) return query;

            if (filter.WithId.HasValue == true)
                query = (ObjectQuery<Group>)query.Where(x => x.Id.Equals(filter.WithId.Value));

            if (filter.WithUrl != null)
                query = (ObjectQuery<Group>)query.Where(x => x.Url.Equals(filter.WithUrl, StringComparison.InvariantCultureIgnoreCase));

            return query;
        }

        public static ObjectQuery<Group> LoadWith(this ObjectQuery<Group> query, GroupDataLoadOptions dlo)
        {
            GroupDataLoadOptions sdlo = (GroupDataLoadOptions)dlo;

            if (sdlo == null) return query;

            return query;
        }

        public static ObjectQuery<Group> OrderBy(this ObjectQuery<Group> query, GroupDataOrderOptions doo)
        {
            return query;
        }
    }
}